﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Abp.AspNetCore.Mvc.Authorization;
using Abp.AspNetCore.Mvc.Extensions;
using Abp.UI;
using FwProject.Authorization.Users;
using FwProject.Car;
using FwProject.Controllers;
using FwProject.Distribution;
using FwProject.Distribution.Dto;
using FwProject.Distribution.Dto.Statistics;
using FwProject.Restaurant;
using FwProject.Users;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using X.PagedList;

namespace FwProject.Web.Mvc.Controllers
{
    [AbpMvcAuthorize]
    public class DistributionReportController : FwProjectControllerBase
    {
        private readonly ICarInfoAppService _carInfoAppService;
        private readonly ILoadCarAppService _loadCarAppService;
        private readonly ILoadingCarAppService _loadingCarAppService;
        private readonly IDistributionAppService _distributionAppService;
        private readonly IDistributionDetailsAppService _distributionDetailsAppService;
        private readonly IUserAppService _userAppService;
        private readonly IDistributionLineAppService _distributionLineAppService;
        private readonly IHostingEnvironment _env;

        public DistributionReportController(ICarInfoAppService carInfoAppService, ILoadCarAppService loadCarAppService,
            ILoadingCarAppService loadingCarAppService, IDistributionAppService distributionAppService, IDistributionDetailsAppService distributionDetailsAppService,
            IUserAppService userAppService, IDistributionLineAppService distributionLineAppService, IHostingEnvironment env)
        {
            _carInfoAppService = carInfoAppService;
            _loadCarAppService = loadCarAppService;
            _loadingCarAppService = loadingCarAppService;
            _distributionAppService = distributionAppService;
            _distributionDetailsAppService = distributionDetailsAppService;
            _userAppService = userAppService;
            _distributionLineAppService = distributionLineAppService;
            _env = env;
        }

        #region 配送报表
        /// <summary>
        /// 配送商品统计
        /// </summary>
        /// <param name="beginTime"></param>
        /// <param name="endTime"></param>
        /// <param name="productName"></param>
        /// <param name="restaurant"></param>
        /// <returns></returns>
        public async Task<IActionResult> DistributionStatistics(DateTime? beginTime, DateTime? endTime, string productName = "", string restaurant = "")
        {

            var data = await _distributionAppService.GetDistributionProductStatisticsAsync(beginTime, endTime, productName, restaurant);
            if (Request.IsAjaxRequest())
            {
                return PartialView("DistributionStatisticsPartial", data);
            }
            return View(data);
        }
        /// <summary>
        /// 配送商品统计导出
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> ExportDistributionStatistics(DateTime? beginTime, DateTime? endTime, string productName = "", string restaurant = "")
        {
            var list = await _distributionAppService.GetDistributionProductStatisticsAsync(beginTime, endTime, productName, restaurant);
            return DoExcel<DistributionProductStatisticsDto>(list, _env);
        }

        /// <summary>
        /// 配送情况统计
        /// </summary>
        /// <param name="restaurantName"></param>
        /// <returns></returns>
        public async Task<IActionResult> DeliverySituation(string restaurantName = "")
        {
            var data = await _distributionAppService.GetDeliverySituationAsync(restaurantName);
            return View(data);
        }

        /// <summary>
        /// 配送情况详情
        /// </summary>
        /// <param name="id"></param>
        /// <param name="ramge"></param>
        /// <returns></returns>
        public async Task<IActionResult> DeliverySituationDetails(int? id,int size, DeliveryTimeRange ramge)
        {
            int pageNumber = id ?? 1;
            if (size == 0)
                size = 20;
            var data = await _distributionAppService.GetDeliverySituationDetailsAsync(pageNumber, size, ramge);

            ViewBag.Range = ramge;
            if (Request.IsAjaxRequest())
                return PartialView("DeliverySituationDetailsPartial", data);

            return View(data);
        }



        /// <summary>
        /// 餐厅配送统计/配送型号统计
        /// </summary>
        /// <param name="beginTime"></param>
        /// <param name="endTime"></param>
        /// <param name="beginTime2"></param>
        /// <param name="endTime2"></param>
        /// <param name="RestaurantName"></param>
        /// <param name="Name"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<IActionResult> RestaurantDistribution(int pageIdx,int size1,int size2, DateTime? beginTime, DateTime? endTime, DateTime? beginTime2, DateTime? endTime2, string RestaurantName, long? DriverName, string key)
        {
            if (pageIdx == 0)
                pageIdx = 1;
            if (size1 == 0)
                size1 = 20;
            if (size2 == 0)
                size2 = 10;

            var list1 = await _distributionAppService.GetRestaurantDistributionListAsync(beginTime, endTime, RestaurantName, DriverName);
            ViewBag.Distributioncount = list1.Sum(o => o.Distributioncount);
            ViewBag.DistributionBycount = list1.Sum(o => o.DistributionBycount);

            ViewBag.Recoverycount = list1.Sum(o => o.Recoverycount);
            ViewBag.RecoveryBycount = list1.Sum(o => o.RecoveryBycount);

            ViewBag.Exchangegoodscount = list1.Sum(o => o.Exchangegoodscount);
            ViewBag.ExchangegoodsBycount = list1.Sum(o => o.ExchangegoodsBycount);

            ViewBag.Damagecount = list1.Sum(o => o.Damagecount);

            ViewBag.Givecount = list1.Sum(o => o.Givecount);
            ViewBag.Givebycount = list1.Sum(o => o.Givebycount);

            ViewBag.Backboxcount = list1.Sum(o => o.Backboxcount);
            ViewBag.Backnumbercount = list1.Sum(o => o.Backnumbercount);
            ViewBag.TotalPrice = list1.Sum(o => o.TotalPrice);

            var list2 = await _distributionDetailsAppService.GetDistributionDetailsListsAsync(beginTime2, endTime2, RestaurantName, DriverName);
            ViewBag.DistributionDetails = list2;

            if (Request.IsAjaxRequest())
            {
                if (key == "1")
                {
                    var restaurantmodel = await _distributionAppService.GetRestaurantDistributionAsync(pageIdx, size1, beginTime, endTime, RestaurantName, DriverName);
                    return PartialView("RestaurantDistributionPartial", restaurantmodel);
                }
                else if (key == "2")
                {
                    var typenumbermodel = await _distributionDetailsAppService.GetDistributionDetailsListAsync(pageIdx, size2, beginTime2, endTime2, RestaurantName, DriverName);
                    return PartialView("TypeNumberDistributionPartial", typenumbermodel);
                }

            }

            return View();
        }
        /// <summary>
        /// 餐厅配送统计导出
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> ExportRestaurantDistribution(string RestaurantName, long? DriverName, DateTime? beginTime, DateTime? endTime)
        {
            var list = await _distributionAppService.GetRestaurantDistributionListAsync(beginTime, endTime,RestaurantName,DriverName);
            return DoExcel<RestaurantDistributionView>(list, _env);
        }
        /// <summary>
        /// 餐厅配送货品统计导出
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> ExportTypeNumberDistribution(string RestaurantName, string DriverName, DateTime? beginTime, DateTime? endTime)
        {
            var list = await _distributionDetailsAppService.GetExportDistributionDetailsAsync(RestaurantName, DriverName, beginTime, endTime);
            return DoExcel<DistributionTypeNumberReportDto>(list, _env);
        }

        /// <summary>
        /// 司机配送统计
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> DriverDistribution(int pageIdx,int size1,int size2, DateTime? beginTime, DateTime? endTime, DateTime? beginTime2, DateTime? endTime2, long? DriverName, string key)
        {
            if (pageIdx == 0)
                pageIdx = 1;
            if (size1 == 0)
                size1 = 20;
            if (size2 == 0)
                size2 = 10;

            var usermodel = await _userAppService.GetByIdUserAsync(AbpSession.UserId.Value);
            var drivermodel = await _userAppService.GetAllByTypeAsync(EmployeeType.司机类型,null, "");

            ViewBag.Driver = drivermodel.Where(o => o.FactoryInfoId == usermodel.FactoryinfoId);


            if (Request.IsAjaxRequest())
            {
                if (key == "1")
                {
                    var restaurantmodel = await _distributionAppService.GetDriverDistributionAsync(pageIdx, size1, beginTime, endTime, DriverName);
                    return PartialView("DriverDistributionPartial", restaurantmodel);
                }
                else if (key == "2")
                {
                    var typenumbermodel = await _distributionAppService.GetDistributiondetailsAsync(pageIdx, size2, beginTime2, endTime2,DriverName);
                    return PartialView("DriverTypeNumberPartial", typenumbermodel);
                }
            }

            return View();
        }
        /// <summary>
        /// 司机配送统计导出
        /// </summary>
        /// <returns></returns>

        public async Task<IActionResult> ExportDriverDistribution(long? DriverName, DateTime? beginTime, DateTime? endTime)
        {
            var list = await _distributionAppService.GetExportDriverDistributionAsync(beginTime, endTime, DriverName);

            return DoExcel<ExportDriverDistributionDto>(list, _env);
        }
        /// <summary>
        /// 司机配送货品统计导出
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> ExportDriverTypeNumber(long? DriverName, DateTime? beginTime, DateTime? endTime)
        {
            var list = await _distributionAppService.GetExportDistributionDetailsAsync(beginTime, endTime, DriverName);
            return DoExcel<ExportDistributionTypeNumberDto>(list, _env);
        }

        /// <summary>
        /// 线路配送统计
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> DistributionLine(int pageIdx,int size, DateTime? beginTime, DateTime? endTime, Guid? LineId)
        {
            if (pageIdx == 0)
                pageIdx = 1;
            if (size == 0)
                size = 10;

            var usermodel = await _userAppService.GetByIdUserAsync(AbpSession.UserId.Value);
            var line = await _distributionLineAppService.GetAllLineAsync();
            //ViewBag.LineName = line.Where(o => o.FactoryInfoid == usermodel.FactoryinfoId);
            ViewBag.Line = line.Select(o => new SelectListItem() { Value = o.Id.ToString(), Text = o.LineName });

            if (Request.IsAjaxRequest())
            {
                var model = await _distributionAppService.GetLineDistributionAsync(pageIdx, size, beginTime, endTime, LineId, "");
                return PartialView("DistributionLinePartial", model);
            }
            return View();
        }
        /// <summary>
        /// 线路配送统计导出
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> ExporDistributionLine(Guid? LineId, DateTime? beginTime, DateTime? endTime)
        {
            var list = await _distributionAppService.GetExportLineDistributionAsync(beginTime, endTime, LineId);
            return DoExcel<DistributionLineViewList>(list, _env);
        }
        /// <summary>
        /// 配送差件汇总
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> DistributionDiff(int? pageIdx, int size, DateTime? beginTime, DateTime? endTime, Guid? LineId, long? DriverId)
        {
            var pa = pageIdx ?? 1;
            if (size == 0)
                size = 20;

            var usermodel = await _userAppService.GetByIdUserAsync(AbpSession.UserId.Value);
            var line = await _distributionLineAppService.GetAllLineAsync();
            //ViewBag.LineName = line.Where(o => o.FactoryInfoid == usermodel.FactoryinfoId);

            ViewBag.Line = line.Select(o => new SelectListItem() { Value = o.Id.ToString(), Text = o.LineName });

            if (Request.IsAjaxRequest())
            {
                var model = await _distributionAppService.GetDistributionDiffAsync(pa, size, beginTime, endTime, LineId, DriverId);
                return PartialView("DistributionDiffPartial", model);
            }
            return View();
        }
        /// <summary>
        /// 配送差件汇总导出
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> ExportDistributionDiff(Guid? LineId, long? DriverId, DateTime? beginTime, DateTime? endTime)
        {
            var list = await _distributionAppService.GetExportDistributionDiffAsync(beginTime, endTime, LineId, DriverId);
            return DoExcel<DistributionDiffView>(list, _env);
        }

        /// <summary>
        /// 当季汇总
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> QuarterlySummary()
        {
            var data = await _distributionAppService.GetQuarterlySummary();
            return View(data);
        }

        /// <summary>
        /// 当季汇总-月详情
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> QuarterlyDetailsM(DateTime time)
        {
            var data = await _distributionAppService.GetQuarterlySummaryMonthData(time);
            ViewBag.Time = time;
            if (Request.IsAjaxRequest())
            {
                return PartialView("QuarterlyDetailsMPartial", data);
            }

            return View(data);
        }

        /// <summary>
        /// 当季汇总-日详情
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public async Task<IActionResult> QuarterlyDetailsD(DateTime time, string type)
        {

            var data = await _distributionAppService.GetQuarterlySummaryDayData(time, type);
            ViewBag.Time = time;
            ViewBag.Type = type;
            if (Request.IsAjaxRequest())
            {
                if (type == "Distribution")
                {
                    return PartialView("QuarterlyDetailsDPartial", data);
                }
                else
                {
                    return PartialView("QuarterlyDetailsDPartial2", data);
                }
            }

            return View(data);
        }

        /// <summary>
        /// 司机实际配送率
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> DriverActualRatio(int pageIdx, int size, DateTime? beginTime, DateTime? endTime, long? DriverId)
        {
            if (pageIdx == 0)
                pageIdx = 1;

            if (size == 0)
                size = 20;

            if (Request.IsAjaxRequest())
            {
                var data = await _distributionAppService.GetDriverActualRatioAsync(pageIdx, size, beginTime, endTime, DriverId);
                return PartialView("DriverActualRatioPartial", data);
            }

            return View();
        }
        /// <summary>
        /// 司机实送率导出
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> ExportDriverActualRatio(long? DriverId, DateTime? beginTime, DateTime? endTime)
        {
            var list = await _distributionAppService.GetExportDriverActualRatioAsync(beginTime, endTime, DriverId);
            return DoExcel<DriverActualRatioOutputDto>(list, _env);
        }

        #endregion

        #region 配送图形报表
        /// <summary>
        /// 月配送总报表图
        /// </summary>
        /// <returns></returns>
        public IActionResult MonthDistributionReportChart()
        {
            return View();
        }

        /// <summary>
        /// 月配送总报表图数据
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> MonthDistributionReportChartData(DateTime time)
        {
            var data = await _distributionAppService.GetDistributionReportChart(time, DateSearchType.Month);
            var days = data.Select(o => o.Days.Substring(o.Days.Length - 2)).ToArray();
            FinaceBar<int> finace = new FinaceBar<int>()
            {
                name = "月配送报表",
                type = "bar",
                data = data.Select(o => o.DeliveryNumber).ToList()
            };

            var option = new
            {
                title = new { text = time.ToString("yyyy-MM") + "月配送总报表" },
                legend = new { axisTick = new { show = false }, data = new string[1] { "配送数" } },
                yAxis = new { type = "value" },
                xAxis = new { boundaryGap = true, type = "category", axisPointer = new { type = "shadow" }, data = days },
                series = new List<FinaceBar<int>> { finace },
            };
            return Json(option);
        }

        /// <summary>
        /// 年配送报表图
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public IActionResult YearDistributionReportChart()
        {
            return View();
        }
        public async Task<IActionResult> YearDistributionReportChartData(string time)
        {
            var year = new DateTime(Int32.Parse(time), 1, 1);
            var data = await _distributionAppService.GetDistributionReportChart(year, DateSearchType.Year);
            var days = data.Select(o => o.Days.Substring(o.Days.Length - 2)).ToArray();
            FinaceBar<int> finace = new FinaceBar<int>()
            {
                name = "年配送报表",
                type = "bar",
                data = data.Select(o => o.DeliveryNumber).ToList()
            };

            var option = new
            {
                title = new { text = time + "年配送总报表" },
                legend = new { axisTick = new { show = false }, data = new string[1] { "配送数" } },
                yAxis = new { type = "value" },
                xAxis = new { boundaryGap = true, type = "category", axisPointer = new { type = "shadow" }, data = days },
                series = new List<FinaceBar<int>> { finace },
            };
            return Json(option);
        }

        /// <summary>
        /// 型号配送月统计图形
        /// </summary>
        /// <returns></returns>
        public IActionResult MonthTypeReportChart()
        {
            return View();
        }

        /// <summary>
        ///  型号配送月统计数据
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> MonthTypeReportData(DateTime time)
        {
            var data = await _distributionAppService.GetTypeDistributionReportData(time, DateSearchType.Month);
            var names = data.Select(o => o.TypeName).ToArray();
            FinaceBar<int> finace = new FinaceBar<int>()
            {
                name = "配送数",
                type = "bar",
                data = data.Select(o => o.DeliveryNumber).ToList()
            };

            var option = new
            {
                title = new { text = time.ToString("yyyy-MM") + "型号月配送图" },
                legend = new { axisTick = new { show = false }, data = new string[1] { "配送数" } },
                yAxis = new { type = "value" },
                xAxis = new { boundaryGap = true, type = "category", axisPointer = new { type = "shadow" }, data = names },
                series = new List<FinaceBar<int>> { finace },
            };
            return Json(option);
        }

        /// <summary>
        /// 型号年配送统计图
        /// </summary>
        /// <returns></returns>
        public IActionResult YearTypeReportChart()
        {
            return View();
        }
        public async Task<IActionResult> YearTypeReportData(string time)
        {
            var year = new DateTime(Int32.Parse(time), 1, 1);
            var data = await _distributionAppService.GetTypeDistributionReportData(year, DateSearchType.Year);
            var names = data.Select(o => o.TypeName).ToArray();
            FinaceBar<int> finace = new FinaceBar<int>()
            {
                name = "配送数",
                type = "bar",
                data = data.Select(o => o.DeliveryNumber).ToList()
            };

            var option = new
            {
                title = new { text = "型号" + time + "年配送图" },
                legend = new { axisTick = new { show = false }, data = new string[1] { "配送数" } },
                yAxis = new { type = "value" },
                xAxis = new { boundaryGap = true, type = "category", axisPointer = new { type = "shadow" }, data = names },
                series = new List<FinaceBar<int>> { finace },
            };
            return Json(option);
        }

        /// <summary>
        /// 司机月配送图
        /// </summary>
        /// <returns></returns>
        public IActionResult MonthDriverReportChart()
        {
            return View();
        }
        public async Task<IActionResult> MonthDriverReportData(DateTime time)
        {
            var data = await _distributionAppService.GetDriverDistributionReportData(time, DateSearchType.Month);
            var names = data.Select(o => o.DriverName).ToArray();
            FinaceBar<int> finace = new FinaceBar<int>()
            {
                name = "配送数",
                type = "bar",
                data = data.Select(o => o.DeliveryNumber).ToList()
            };

            var option = new
            {
                title = new { text = "司机" + time.ToString("yyyy-MM") + "月配送图" },
                legend = new { axisTick = new { show = false }, data = new string[1] { "配送数" } },
                yAxis = new { type = "value" },
                xAxis = new { boundaryGap = true, type = "category", axisPointer = new { type = "shadow" }, data = names },
                series = new List<FinaceBar<int>> { finace },
            };
            return Json(option);
        }

        /// <summary>
        /// 司机年配送图
        /// </summary>
        /// <returns></returns>
        public IActionResult YearDriverReportChart()
        {
            return View();
        }
        public async Task<IActionResult> YearDriverReportData(string time)
        {
            var year = new DateTime(Int32.Parse(time), 1, 1);
            var data = await _distributionAppService.GetDriverDistributionReportData(year, DateSearchType.Year);
            var names = data.Select(o => o.DriverName).ToArray();
            FinaceBar<int> finace = new FinaceBar<int>()
            {
                name = "配送数",
                type = "bar",
                data = data.Select(o => o.DeliveryNumber).ToList()
            };

            var option = new
            {
                title = new { text = "司机" + time + "年配送图" },
                legend = new { axisTick = new { show = false }, data = new string[1] { "配送数" } },
                yAxis = new { type = "value" },
                xAxis = new { boundaryGap = true, type = "category", axisPointer = new { type = "shadow" }, data = names },
                series = new List<FinaceBar<int>> { finace },
            };
            return Json(option);
        }

        /// <summary>
        /// 配送与回收报表图（天）
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public IActionResult DistributionAndRecyclingReportChart()
        {
            return View();
        }

        /// <summary>
        /// 配送与回收报表图（月）
        /// </summary>
        /// <returns></returns>
        public IActionResult DistributionAndRecyclingMonthReportChart()
        {
            return View();
        }
        public async Task<IActionResult> DistributionAndRecyclingReportData(DateTime time, DateSearchType type)
        {
            var data = await _distributionAppService.GetDistributionAndRecyclingReportData(time, type);
            var names = data.Select(o => o.GroupName.Substring(o.GroupName.Length - 2)).ToArray();
            FinaceBar<int> finace1 = new FinaceBar<int>()
            {
                name = "配送数",
                type = "bar",
                data = data.Select(o => o.Distribution).ToList()
            };

            FinaceBar<int> finace2 = new FinaceBar<int>()
            {
                name = "回收数",
                type = "bar",
                data = data.Select(o => o.Recovered).ToList()
            };

            var option = new
            {
                title = new { text = time.ToString("yyyy-MM") + "配送与回收" },
                legend = new { axisTick = new { show = false }, data = new string[2] { "配送数", "回收数" } },
                yAxis = new { type = "value" },
                xAxis = new { boundaryGap = true, type = "category", axisPointer = new { type = "shadow" }, data = names },
                series = new List<FinaceBar<int>> { finace1, finace2 },
            };
            return Json(option);
        }


        /// <summary>
        /// 配送与回收报表图（司机）
        /// </summary>
        /// <returns></returns>
        public IActionResult DistributionAndRecyclingByDriverReportChart()
        {
            return View();
        }
        public async Task<IActionResult> DistributionAndRecyclingByDriverReportData(DateTime time)
        {
            var data = await _distributionAppService.GetDistributionAndRecyclingByDriverReportData(time);
            var names = data.Select(o => o.GroupName).ToArray();
            FinaceBar<int> finace1 = new FinaceBar<int>()
            {
                name = "配送数",
                type = "bar",
                data = data.Select(o => o.Distribution).ToList()
            };

            FinaceBar<int> finace2 = new FinaceBar<int>()
            {
                name = "回收数",
                type = "bar",
                data = data.Select(o => o.Recovered).ToList()
            };

            var option = new
            {
                title = new { text = time.ToString("yyyy-MM") + "配送与回收" },
                legend = new { axisTick = new { show = false }, data = new string[2] { "配送数", "回收数" } },
                yAxis = new { type = "value" },
                xAxis = new { boundaryGap = true, type = "category", axisPointer = new { type = "shadow" }, data = names },
                series = new List<FinaceBar<int>> { finace1, finace2 },
            };
            return Json(option);
        }
        #endregion


        public async Task<IActionResult> GetTodayStatisticsData()
        {
            var data = await _distributionAppService.GetHomeTodayStatistics();
            return Json(data);
        }
    }
}